
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using SimpleJSON;

namespace HD{

public class Factory<E, R> where R : class
{
	public Factory(){}

	protected Dictionary<E, string> mTypeDict = new Dictionary<E, string>();  
	protected System.Object[] mArgs = new System.Object[1];

	public void Register<T>(E enumType)
	{
		DebugUtil.Assert(mTypeDict.ContainsKey(enumType) == false);
		
		mTypeDict.Add(enumType, typeof(T).ToString());
	}

	public virtual R Create(E enumType, Object arg = null)
	{
		return Create(enumType, arg, null);
	}

	public virtual List<R> Create(List<E> enumTypeList, Object arg = null)
	{
		if (enumTypeList == null || enumTypeList.Count == 0)
			return null;

		List<R> iList = new List<R>();
		foreach(E enumType in enumTypeList)
		{
			iList.Add(Create(enumType, arg));
		}

		return iList;
	}

	protected virtual R Create(E enumType, Object arg, JSONClass dataDict)
	{
		DebugUtil.Assert(mTypeDict.ContainsKey(enumType));
		
		mArgs[0] = arg;
		Type internal_type = Type.GetType(mTypeDict[enumType]);

		object instance = Activator.CreateInstance(internal_type, mArgs);

		if (dataDict != null)
		{
			FieldInfo[] fi = internal_type.GetFields(BindingFlags.Instance | BindingFlags.Public);
		
			foreach (FieldInfo m in fi) 
			{
				HD.Reflection.SetFieldValue(instance, m, dataDict[m.Name]);
			}
		}
		
		return instance as R;
	}
}

} // HD


